import 'dart:async';
import 'dart:ui';
import 'dart:ui' as ui;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:sensors/sensors.dart';

void main() {
  runApp(MaterialApp(home: MyApp()));
}

//const String pic = 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3984473917,238095211&fm=26&gp=0.jpg';
//const String pic = 'https://t7.baidu.com/it/u=378254553,3884800361&fm=79&app=86&size=h300&n=0&g=4n&f=jpeg?sec=1591842684&t=2077ca72bcd89d7a91ad96e10b71418c';
//const String pic = 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3058921518,3155490896&fm=26&gp=0.jpg';
const String pic = 'https://pic.3gbizhi.com/2020/0509/20200509045555273.jpg';

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  ui.Image _sourceImage;
  double _left = 0, _right = 0, _top = 0, _bottom = 0;
  double _scaleRate = 0.9, _gyroscopeRate = 6;
  double _minPxForMove = 0.4;

  @override
  void initState() {
    super.initState();
    print("屏幕宽高 == ${window.physicalSize}");
    ui.Image uiImage;

    _loadAssetImage("assets/images/cover_img.jpg").then((assetImage) {
      uiImage = assetImage;
    }).whenComplete(() {
      _sourceImage = uiImage;

      _downloadImageAndGetImageInfo().then((image) {
        uiImage = image;
      }).whenComplete(() {
        _sourceImage = uiImage;
        print("原图片宽度 == ${_sourceImage.width}");
        print("原图片高度 == ${_sourceImage.height}");

        setState(() {
          _left = 0 +
              (_sourceImage.width - _sourceImage.width.toDouble() * _scaleRate);
          _top = 0 +
              (_sourceImage.height -
                  _sourceImage.height.toDouble() * _scaleRate);
          _right = _sourceImage.width.toDouble() * _scaleRate;
          _bottom = _sourceImage.height.toDouble() * _scaleRate;
        });

        gyroscopeEvents.listen((GyroscopeEvent event) {
//          print(event);

          double x = event.x;
          double y = event.y;
          if (x.abs() * _gyroscopeRate > _minPxForMove) {
            if (x < 0) {
              // 下移
              _bottom += -(x * _gyroscopeRate);
              _top += -(x * _gyroscopeRate);
              if (_bottom >= _sourceImage.height) {
                _bottom = _sourceImage.height.toDouble();
                _top = 0 +
                    2 *
                        (_sourceImage.height -
                            _sourceImage.height.toDouble() * _scaleRate);
              }
            } else {
              // 上移
              _top -= x * _gyroscopeRate;
              _bottom -= x * _gyroscopeRate;
              if (_top <= 0) {
                _bottom = _sourceImage.height -
                    2 *
                        (_sourceImage.height -
                            _sourceImage.height.toDouble() * _scaleRate);
                _top = 0;
              }
            }
            setState(() {});
          }
          if (y.abs() * _gyroscopeRate > _minPxForMove) {
            if (y < 0) {
              // 右移
              _left += -(y * _gyroscopeRate);
              _right += -(y * _gyroscopeRate);
              if (_right >= _sourceImage.width) {
                _right = _sourceImage.width.toDouble();
                _left = 2 *
                    (_sourceImage.width -
                        _sourceImage.width.toDouble() * _scaleRate);
              }
            } else {
              // 左移
              _left -= (y * _gyroscopeRate);
              _right -= (y * _gyroscopeRate);
              if (_left <= 0) {
                _left = 0;
                _right = _sourceImage.width -
                    2 *
                        (_sourceImage.width -
                            _sourceImage.width.toDouble() * _scaleRate);
              }
            }
            setState(() {});
          }
        });
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    ScreenUtil.init(context,
        width: 1080, height: 1920, allowFontScaling: false);

    return Scaffold(
      appBar: AppBar(
        title: Text("根据陀螺仪裁剪图片"),
      ),
      body: Container(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Image.network(
              pic,
              height: 375.h,
              width: 500.w,
            ),
            Container(
                color: Colors.green,
                child: CustomPaint(
                  painter:
                      ImageClipper(_sourceImage, _left, _right, _top, _bottom),
                  size: Size(double.infinity, 620.h),
                )),
          ],
        ),
      ),
    );
  }

  Future<ui.Image> _downloadImageAndGetImageInfo() async {
    ImageStream imageStream = NetworkImage(pic).resolve(ImageConfiguration());
    Completer<ui.Image> completer = Completer<ui.Image>();
    void imageListener(ImageInfo info, bool synchronousCall) {
      ui.Image image = info.image;
      completer.complete(image);
      imageStream.removeListener(ImageStreamListener(imageListener));
    }

    imageStream.addListener(ImageStreamListener(imageListener));
    return completer.future;
  }

  Future<ui.Image> _loadAssetImage(String assetUri) async {
    ImageStream imageStream =
        AssetImage(assetUri).resolve(ImageConfiguration());
    Completer<ui.Image> completer = Completer<ui.Image>();
    void imageListener(ImageInfo info, bool synchronousCall) {
      ui.Image image = info.image;
      completer.complete(image);
      imageStream.removeListener(ImageStreamListener(imageListener));
    }
    imageStream.addListener(ImageStreamListener(imageListener));
    return completer.future;
  }
}

/// 图片裁剪
class ImageClipper extends CustomPainter {
  final ui.Image image;
  double left;
  double right;
  double top;
  double bottom;

  ImageClipper(this.image, this.left, this.right, this.top, this.bottom);

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint();
    print("paint");
    if (image == null) {
      return;
    }
    // 用于图片裁剪的函数，具体含义看文档
    canvas.drawImageRect(image, Rect.fromLTRB(left, top, right, bottom),
        Rect.fromLTWH(0, 0, size.width, size.height), paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}
